package com.zhiche.lisa.bms.service.prepay.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhiche.lisa.bms.dao.mapper.prepay.PrepayBillMapper;
import com.zhiche.lisa.bms.dao.mapper.price.PricePurchaseDtlMapper;
import com.zhiche.lisa.bms.dao.model.bill.BillDetail;
import com.zhiche.lisa.bms.dao.model.contract.Contract;
import com.zhiche.lisa.bms.dao.model.contract.ContractFleetDtl;
import com.zhiche.lisa.bms.dao.model.fee.FeePayable;
import com.zhiche.lisa.bms.dao.model.pay.PayApplyDtlPrepay;
import com.zhiche.lisa.bms.dao.model.prepay.PrepayBill;
import com.zhiche.lisa.bms.dao.model.price.PriceDeductRate;
import com.zhiche.lisa.bms.dao.model.waybill.WaybillState;
import com.zhiche.lisa.bms.pojo.dto.util.FcPayApplyDTO;
import com.zhiche.lisa.bms.pojo.dto.util.FcPayApplyReturnDTO;
import com.zhiche.lisa.bms.pojo.vo.prepay.PrepayBillPertrolVO;
import com.zhiche.lisa.bms.pojo.vo.price.PricePurchaseDetailVO;
import com.zhiche.lisa.bms.service.bill.BillDetailService;
import com.zhiche.lisa.bms.service.contract.ContractFleetDtlService;
import com.zhiche.lisa.bms.service.fee.FeePayableService;
import com.zhiche.lisa.bms.service.fee.impl.FeePayableServiceImpl;
import com.zhiche.lisa.bms.service.pay.PayApplyDtlPrepayService;
import com.zhiche.lisa.bms.service.prepay.PrepayBillService;
import com.zhiche.lisa.bms.service.price.PriceDeductRateService;
import com.zhiche.lisa.bms.service.price.PricePurchaseService;
import com.zhiche.lisa.bms.service.utils.PayApiUtil;
import com.zhiche.lisa.bms.service.waybill.WaybillStateService;
import com.zhiche.lisa.core.supports.BaseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 预付账单 服务实现类
 * </p>
 *
 * @author zhangkun
 * @since 2018-09-20
 */
@Service
public class PrepayBillServiceImpl extends ServiceImpl<PrepayBillMapper, PrepayBill> implements PrepayBillService {
    private static final Logger LOGGER = LoggerFactory.getLogger(FeePayableServiceImpl.class);
    @Autowired
    private PriceDeductRateService priceDeductRateService;
    @Autowired
    private FeePayableService feePayableService;
    @Autowired
    private PricePurchaseService pricePurchaseService;
    @Autowired
    private BillDetailService billDetailService;
    @Autowired
    private PayApplyDtlPrepayService payApplyDtlPrepayService;
    @Autowired
    private ContractFleetDtlService contractFleetDtlService;
    @Autowired
    private PayApiUtil payApiUtil;

    @Autowired
    private PricePurchaseDtlMapper pricePurchaseDtlMapper;
    @Autowired
    private WaybillStateService waybillStateService;

    /**
     * 分页查询
     *
     * @param page
     */
    @Override
    public Page<PrepayBill> queryPrepayBillPage(Page<PrepayBill> page) {
        if (page == null) {
            throw new BaseException("分页参数不为空");
        }
        Map<String, Object> cn = page.getCondition();
        Wrapper<PrepayBill> ew = buildCondition(cn);
        ew.orderBy("gmt_create desc, id desc");
        List<PrepayBill> prepayBillList = baseMapper.selectPage(page, ew);
        page.setRecords(prepayBillList);
        return page;
    }

    /**
     * 根据条件获取所有匹配数据
     *
     * @param condition
     * @return
     */
    @Override
    public List<PrepayBill> queryPrepayBillList(Map<String, Object> condition) {
        Wrapper<PrepayBill> ew = buildCondition(condition);
        ew.orderBy("gmt_create desc, id desc");
        List<PrepayBill> prepayBillList = baseMapper.selectList(ew);
        return prepayBillList;
    }

    /**
     * 获取指定数据列
     *
     * @param appointProperty
     * @param val
     * @return
     */
    @Override
    public List<Object> selectPrepayBillAppoint(String appointProperty, String val) {
        EntityWrapper<PrepayBill> prepayBillEntityWrapper = new EntityWrapper<>();
        if ("driverName".equals(appointProperty)) {
            prepayBillEntityWrapper.setSqlSelect("driver_name");
            prepayBillEntityWrapper.like("driver_name", val);
            return this.selectObjs(prepayBillEntityWrapper);
        } else {
            return null;
        }
    }

    private Wrapper<PrepayBill> buildCondition(Map<String, Object> condition) {
        Wrapper<PrepayBill> ew = new EntityWrapper<>();
        if (!Objects.isNull(condition) && !condition.isEmpty()) {
            //根据订单号查询
            Object orderCode = condition.get("orderCode");
            if (!StringUtils.isEmpty(orderCode)) {
                String[] oder = orderCode.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("order_code", oder);
            }
            // 根据OTM运单号查询
            Object waybillId = condition.get("waybillId");
            if (!StringUtils.isEmpty(waybillId)) {
                String[] oder = waybillId.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("waybill_id", oder);
            }
            // 根据状态查询
            Object status = condition.get("status");
            if (!StringUtils.isEmpty(status)) {
                ew.eq("status", status);
            }
            // 根据状态查询
            Object statusList = condition.get("statusList");
            if (!StringUtils.isEmpty(statusList)) {
                String[] statusArray = statusList.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("status", statusArray);
            }
            // OTM运单号明细
            Object waybillDtlId = condition.get("waybillDtlId");
            if (!StringUtils.isEmpty(waybillDtlId)) {
                ew.eq("waybill_dtl_id", waybillDtlId);
            }
            // OTM运单号明细-批量
            Object waybillDtlIdList = condition.get("waybillDtlIdList");
            if (Objects.nonNull(waybillDtlIdList) && !StringUtils.isEmpty(waybillDtlIdList.toString())) {
                String[] waybillDtlIdArray = waybillDtlIdList.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("waybill_dtl_id", waybillDtlIdArray);
            }
            //根据车架号查询
            Object vin = condition.get("vin");
            if (!StringUtils.isEmpty(vin)) {
                ew.eq("vin", vin);
            }
            // 预付类型
            Object prepayType = condition.get("prepayType");
            if (!StringUtils.isEmpty(prepayType)) {
                ew.eq("prepay_type", prepayType);
            }
            // 一桶油
            Object firstBarrelOil = condition.get("creator");
            if (!StringUtils.isEmpty(firstBarrelOil)) {
                ew.eq("creator", firstBarrelOil);
            }
            Object driverName = condition.get("driverName");
            if (!StringUtils.isEmpty(driverName)) {
                ew.eq("driver_name", driverName);
            }
            // 客户运单号
            Object cusWaybill = condition.get("cusWaybill");
            if (!StringUtils.isEmpty(cusWaybill)) {
                ew.eq("cus_waybill", cusWaybill);
            }
            // 客户运单号-批量
            Object cusWaybillList = condition.get("cusWaybillList");
            if (Objects.nonNull(cusWaybillList) && !StringUtils.isEmpty(cusWaybillList.toString())) {
                String[] cusWaybillArray = cusWaybillList.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("cus_waybill", cusWaybillArray);
            }
            // 加油确认状态
            Object pertrolOilStatus = condition.get("pertrolOilStatus");
            if (!StringUtils.isEmpty(pertrolOilStatus)) {
                ew.eq("pertrol_oil_status", pertrolOilStatus);
            }
            // 车队
            Object fleetId = condition.get("fleetId");
            if (Objects.nonNull(fleetId) && !StringUtils.isEmpty(fleetId.toString())) {
                ew.eq("fleet_id", fleetId);
            }
            // 加油确认开始时间
            Object confirmDateArray = condition.get("confirmDateArray");
            if (Objects.nonNull(confirmDateArray)) {
                JSONArray jsonArray = JSONArray.parseArray(JSONObject.toJSONString(confirmDateArray));
                if (Objects.nonNull(jsonArray) && jsonArray.size() == 2) {
                    String startTime = jsonArray.get(0).toString() + " 00:00:00";
                    String endTime = jsonArray.get(1).toString() + " 23:59:59";
                    ew.ge("pertrol_oil_date", startTime);
                    ew.le("pertrol_oil_date", endTime);
                }
            }
            Object gmtCeateStart = condition.get("gmtCreateStart");
            if (Objects.nonNull(gmtCeateStart) && !StringUtils.isEmpty(gmtCeateStart)) {
                ew.ge("gmt_create", gmtCeateStart.toString());
            }
            Object gmtCeateEnd = condition.get("gmtCreateEnd");
            if (Objects.nonNull(gmtCeateEnd) && !StringUtils.isEmpty(gmtCeateEnd)) {
                ew.le("gmt_create", gmtCeateEnd.toString());
            }
            Object payState = condition.get("payState");
            if (Objects.nonNull(payState) && !StringUtils.isEmpty(payState.toString())) {
                ew.eq("pay_state", payState);
            }
        }
        //ew.orderBy("gmt_create", true);
        return ew;
    }

    /**
     * 生成预付账单(预算比例方式)
     *
     * @param feePayable
     * @param contract
     */
    @Override
    public void insertPrepayBill(FeePayable feePayable, Contract contract) {
        try {
            PrepayBill prepayBill = bindDefaultPrepayBillByFeePable(feePayable);

            /**
             * 2019-06-04 修改 - 当有合同却没有报价单的时候根据标准价生成预付
             */
            if (Objects.nonNull(contract)) {
                if (Objects.nonNull(feePayable.getActualAmt()) && BigDecimal.ZERO.compareTo(feePayable.getActualAmt()) != 0) {
                    // 根据合同价生成预付单
                    createPrepayBillByActualPrice(contract, feePayable, prepayBill);
                } else if (Objects.nonNull(feePayable.getEstAmt()) && BigDecimal.ZERO.compareTo(feePayable.getEstAmt()) != 0) {
                    // 根据标准价生成预付单
                    createPrepayBillByEstPrice(contract, feePayable, prepayBill);
                }
            }
            if (prepayBill.getActualAmt() != null) {
                prepayBill.setActualAmt(prepayBill.getActualAmt().setScale(2, BigDecimal.ROUND_HALF_UP));
            }
        } catch (BaseException e) {
            LOGGER.error("PrepayBillServiceImpl.insertPrepayBill ERROR: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER.error("PrepayBillServiceImpl.insertPrepayBill ERROR: {}", e.getMessage());
            throw new BaseException("生成预付账单错误");
        }
    }

    /**
     * 根据合同价生成预付单
     *
     * @param contract
     * @param feePayable
     * @param prepayBill
     */
    private void createPrepayBillByActualPrice(Contract contract, FeePayable feePayable, PrepayBill prepayBill) {
        //根据合同寻找车队详明
        contract.setFleetIds(feePayable.getFleetId().toString());
        List<ContractFleetDtl> contractFleetDtls = contractFleetDtlService.selectContractFleetDtlByContract(contract);
        if (!CollectionUtils.isEmpty(contractFleetDtls)) {
            if (contract.getContractType() == 0) {
                //临时合同生成方式
                Integer countByOrderCode = feePayableService.getCountByOrderCode(feePayable.getOrderCode());
                contractFleetDtls.forEach(contractFleetDtl -> {
                    tempContractPrepayBill(feePayable, contractFleetDtl, prepayBill, countByOrderCode);
                });
            } else if (contract.getContractType() == 1) {
                //正式合同生成方式
                contractFleetDtls.forEach(contractFleetDtl -> {
                    officialPrepayBill(feePayable, contractFleetDtl, prepayBill, false);
                });
            }
        }
    }

    /**
     * 根据合同价生成预付单
     *
     * @param contract
     * @param feePayable
     */
    private void createPrepayBillByActualPrice(Contract contract, FeePayable feePayable) {
        //根据合同寻找车队详明
        contract.setFleetIds(feePayable.getFleetId().toString());
        List<ContractFleetDtl> contractFleetDtls = contractFleetDtlService.selectContractFleetDtlByContract(contract);
        if (!CollectionUtils.isEmpty(contractFleetDtls)) {
            if (contract.getContractType() == 0) {
                //临时合同生成方式
                Integer countByOrderCode = feePayableService.getCountByOrderCode(feePayable.getOrderCode());
                contractFleetDtls.forEach(contractFleetDtl -> {
                    if (Integer.valueOf(0).equals(contractFleetDtl.getIsPrepay())) {
                        if (contractFleetDtl.getOilPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getOilPrepayRate()) != 0) {
                            PrepayBill prepayBill = bindDefaultPrepayBillByFeePable(feePayable);
                            tempContractPrepayBill(feePayable, contractFleetDtl, prepayBill, countByOrderCode, true);
                        }
                        if (contractFleetDtl.getCashPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getCashPrepayRate()) != 0) {
                            PrepayBill prepayBill = bindDefaultPrepayBillByFeePable(feePayable);
                            tempContractPrepayBill(feePayable, contractFleetDtl, prepayBill, countByOrderCode, false);
                        }
                    }
                });
            } else if (contract.getContractType() == 1) {
                //正式合同生成方式
                contractFleetDtls.forEach(contractFleetDtl -> {
                    if (Integer.valueOf(0).equals(contractFleetDtl.getIsPrepay())) {
                        if (contractFleetDtl.getOilPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getOilPrepayRate()) != 0) {
                            PrepayBill prepayBill = bindDefaultPrepayBillByFeePable(feePayable);
                            officialPrepayBill(feePayable, contractFleetDtl, prepayBill, false, true);
                        }
                        if (contractFleetDtl.getCashPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getCashPrepayRate()) != 0) {
                            PrepayBill prepayBill = bindDefaultPrepayBillByFeePable(feePayable);
                            officialPrepayBill(feePayable, contractFleetDtl, prepayBill, false, false);
                        }
                    }
                });
            }
        }
    }

    /**
     * 临时合同生成预付账单
     *
     * @param feePayable
     * @param contractFleetDtl
     * @param prepayBill
     * @param countByOrderCode
     */
    private void tempContractPrepayBill(FeePayable feePayable, ContractFleetDtl contractFleetDtl, PrepayBill prepayBill,
                                        Integer countByOrderCode) {
        if (Integer.valueOf(0).equals(contractFleetDtl.getIsPrepay())) {

            if (feePayable.getActualAmt() == null) {
                feePayable.setActualAmt(BigDecimal.ZERO);
            }
            if (contractFleetDtl.getOilPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getOilPrepayRate()) != 0) {
                // 油卡
                prepayBill.setPrepayType(0);
                if (!Integer.valueOf(0).equals(countByOrderCode)) {
                    prepayBill.setPrepayOil(
                            contractFleetDtl.getOilPrepayRate().divide(BigDecimal.valueOf(countByOrderCode), 6, BigDecimal.ROUND_HALF_UP)
                                    .setScale(2, BigDecimal.ROUND_HALF_UP));
                } else {
                    prepayBill.setPrepayOil(contractFleetDtl.getOilPrepayRate());
                }
                prepayBill.setPrepaySum(prepayBill.getPrepayOil());
                // this.insert(prepayBill);
                // 2019-04-15 验证是否存在
                checkPrepayBillExistAndInsert(prepayBill);
                prepayBill.setPrepayType(null);
                prepayBill.setPrepayOil(null);
            } else if (contractFleetDtl.getCashPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getCashPrepayRate()) != 0) {
                // 现金
                prepayBill.setPrepayType(1);
                if (!Integer.valueOf(0).equals(countByOrderCode)) {
                    prepayBill.setPrepayCash(
                            contractFleetDtl.getCashPrepayRate().divide(BigDecimal.valueOf(countByOrderCode), 6, BigDecimal.ROUND_HALF_UP)
                                    .setScale(2, BigDecimal.ROUND_HALF_UP));
                } else {
                    prepayBill.setPrepayCash(contractFleetDtl.getCashPrepayRate());
                }
                prepayBill.setPrepaySum(prepayBill.getPrepayCash());
                // this.insert(prepayBill);
                // 2019-04-15 验证是否存在
                checkPrepayBillExistAndInsert(prepayBill);
                prepayBill.setPrepayType(null);
                prepayBill.setPrepayCash(null);
            }
        }
    }

    private void tempContractPrepayBill(FeePayable feePayable, ContractFleetDtl contractFleetDtl, PrepayBill prepayBill,
                                        Integer countByOrderCode, boolean isOil) {

        if (Integer.valueOf(0).equals(contractFleetDtl.getIsPrepay())) {

            if (feePayable.getActualAmt() == null) {
                feePayable.setActualAmt(BigDecimal.ZERO);
            }
            if (isOil) {
                if (contractFleetDtl.getOilPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getOilPrepayRate()) != 0) {
                    // 油卡
                    prepayBill.setPrepayType(0);
                    if (!Integer.valueOf(0).equals(countByOrderCode)) {
                        prepayBill.setPrepayOil(
                                contractFleetDtl.getOilPrepayRate().divide(BigDecimal.valueOf(countByOrderCode), 6, BigDecimal.ROUND_HALF_UP)
                                        .setScale(2, BigDecimal.ROUND_HALF_UP));
                    } else {
                        prepayBill.setPrepayOil(contractFleetDtl.getOilPrepayRate());
                    }
                    prepayBill.setPrepaySum(prepayBill.getPrepayOil());
                    if (prepayBill.getActualAmt() != null) {
                        prepayBill.setActualAmt(prepayBill.getActualAmt().setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                    checkPrepayBillExistAndInsert(prepayBill);
                    prepayBill.setPrepayType(null);
                    prepayBill.setPrepayOil(null);
                }
            } else {
                if (contractFleetDtl.getCashPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getCashPrepayRate()) != 0) {
                    // 现金
                    prepayBill.setPrepayType(1);
                    if (!Integer.valueOf(0).equals(countByOrderCode)) {
                        prepayBill.setPrepayCash(
                                contractFleetDtl.getCashPrepayRate().divide(BigDecimal.valueOf(countByOrderCode), 6, BigDecimal.ROUND_HALF_UP)
                                        .setScale(2, BigDecimal.ROUND_HALF_UP));
                    } else {
                        prepayBill.setPrepayCash(contractFleetDtl.getCashPrepayRate());
                    }
                    prepayBill.setPrepaySum(prepayBill.getPrepayCash());
                    if (prepayBill.getActualAmt() != null) {
                        prepayBill.setActualAmt(prepayBill.getActualAmt().setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                    checkPrepayBillExistAndInsert(prepayBill);
                    prepayBill.setPrepayType(null);
                    prepayBill.setPrepayCash(null);
                }
            }
        }
    }


    /**
     * 正式合同 生成预付账单
     *
     * @param feePayable
     * @param contractFleetDtl
     * @param prepayBill
     * @param isEst
     */
    private void officialPrepayBill(FeePayable feePayable, ContractFleetDtl contractFleetDtl, PrepayBill prepayBill, boolean isEst) {
        if (feePayable.getActualAmt() == null) {
            feePayable.setActualAmt(BigDecimal.ZERO);
        }
        if (Integer.valueOf(0).equals(contractFleetDtl.getIsPrepay())) {
            if (contractFleetDtl.getOilPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getOilPrepayRate()) != 0) {
                prepayBill.setPrepayType(0);
                if (isEst) {
                    prepayBill.setPrepayOil(contractFleetDtl.getOilPrepayRate().multiply(feePayable.getEstAmt()));
                } else {
                    prepayBill.setPrepayOil(contractFleetDtl.getOilPrepayRate().multiply(feePayable.getActualAmt()));
                }
                prepayBill.setPrepaySum(prepayBill.getPrepayOil());
                // 2019-04-15 验证是否存在
                checkPrepayBillExistAndInsert(prepayBill);
                prepayBill.setPrepayType(null);
                prepayBill.setPrepayOil(null);
            } else if (contractFleetDtl.getCashPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getCashPrepayRate()) != 0) {
                prepayBill.setPrepayType(1);
                if (isEst) {
                    prepayBill.setPrepayCash(contractFleetDtl.getCashPrepayRate().multiply(feePayable.getEstAmt()));
                } else {
                    prepayBill.setPrepayCash(contractFleetDtl.getCashPrepayRate().multiply(feePayable.getActualAmt()));
                }
                prepayBill.setPrepaySum(prepayBill.getPrepayCash());
                // 2019-04-15 验证是否存在
                checkPrepayBillExistAndInsert(prepayBill);
                prepayBill.setPrepayType(null);
                prepayBill.setPrepayCash(null);
            }
        }
    }

    /**
     * 正式合同 生成预付账单
     *
     * @param feePayable
     * @param contractFleetDtl
     * @param prepayBill
     * @param isEst
     */
    private void officialPrepayBill(FeePayable feePayable, ContractFleetDtl contractFleetDtl, PrepayBill prepayBill, boolean isEst,
                                    boolean isOil) {
        if (feePayable.getActualAmt() == null) {
            feePayable.setActualAmt(BigDecimal.ZERO);
        }
        if (Integer.valueOf(0).equals(contractFleetDtl.getIsPrepay())) {
            if (isOil) {
                if (contractFleetDtl.getOilPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getOilPrepayRate()) != 0) {
                    prepayBill.setPrepayType(0);
                    if (isEst) {
                        prepayBill.setPrepayOil(contractFleetDtl.getOilPrepayRate().multiply(feePayable.getEstAmt()));
                    } else {
                        prepayBill.setPrepayOil(contractFleetDtl.getOilPrepayRate().multiply(feePayable.getActualAmt()));
                    }
                    prepayBill.setPrepaySum(prepayBill.getPrepayOil());
                    if (prepayBill.getActualAmt() != null) {
                        prepayBill.setActualAmt(prepayBill.getActualAmt().setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                    checkPrepayBillExistAndInsert(prepayBill);
                    prepayBill.setPrepayType(null);
                    prepayBill.setPrepayOil(null);
                }
            } else {
                if (contractFleetDtl.getCashPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getCashPrepayRate()) != 0) {
                    prepayBill.setPrepayType(1);
                    if (isEst) {
                        prepayBill.setPrepayCash(contractFleetDtl.getCashPrepayRate().multiply(feePayable.getEstAmt()));
                    } else {
                        prepayBill.setPrepayCash(contractFleetDtl.getCashPrepayRate().multiply(feePayable.getActualAmt()));
                    }
                    prepayBill.setPrepaySum(prepayBill.getPrepayCash());
                    if (prepayBill.getActualAmt() != null) {
                        prepayBill.setActualAmt(prepayBill.getActualAmt().setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                    checkPrepayBillExistAndInsert(prepayBill);
                    prepayBill.setPrepayType(null);
                    prepayBill.setPrepayCash(null);
                }
            }
        }
    }


    /**
     * 根据标准价生成预付账单
     *
     * @param contract
     * @param feePayable
     * @param prepayBill
     */
    private void createPrepayBillByEstPrice(Contract contract, FeePayable feePayable, PrepayBill prepayBill) {
        //根据合同寻找车队详明
        contract.setFleetIds(feePayable.getFleetId().toString());
        List<ContractFleetDtl> contractFleetDtls = contractFleetDtlService.selectContractFleetDtlByContract(contract);
        if (!CollectionUtils.isEmpty(contractFleetDtls)) {
            if (contract.getContractType() == 0) {
                //临时合同生成方式
                Integer countByOrderCode = feePayableService.getCountByOrderCode(feePayable.getOrderCode());
                contractFleetDtls.forEach(contractFleetDtl -> {
                    // 临时合同
                    tempContractPrepayBill(feePayable, contractFleetDtl, prepayBill, countByOrderCode);
                });
            } else if (contract.getContractType() == 1) {
                //正式合同生成方式
                contractFleetDtls.forEach(contractFleetDtl -> {
                    officialPrepayBill(feePayable, contractFleetDtl, prepayBill, true);
                });
            }
        }
    }

    /**
     * 根据标准价生成预付账单
     *
     * @param contract
     * @param feePayable
     */
    private void createPrepayBillByEstPrice(Contract contract, FeePayable feePayable) {
        //根据合同寻找车队详明
        contract.setFleetIds(feePayable.getFleetId().toString());
        List<ContractFleetDtl> contractFleetDtls = contractFleetDtlService.selectContractFleetDtlByContract(contract);
        if (!CollectionUtils.isEmpty(contractFleetDtls)) {
            if (contract.getContractType() == 0) {
                //临时合同生成方式
                Integer countByOrderCode = feePayableService.getCountByOrderCode(feePayable.getOrderCode());
                contractFleetDtls.forEach(contractFleetDtl -> {
                    // 临时合同
                    if (Integer.valueOf(0).equals(contractFleetDtl.getIsPrepay())) {
                        if (contractFleetDtl.getOilPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getOilPrepayRate()) != 0) {
                            PrepayBill prepayBill = bindDefaultPrepayBillByFeePable(feePayable);
                            tempContractPrepayBill(feePayable, contractFleetDtl, prepayBill, countByOrderCode, true);
                        }
                        if (contractFleetDtl.getCashPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getCashPrepayRate()) != 0) {
                            PrepayBill prepayBill = bindDefaultPrepayBillByFeePable(feePayable);
                            tempContractPrepayBill(feePayable, contractFleetDtl, prepayBill, countByOrderCode, false);
                        }
                    }
                });
            } else if (contract.getContractType() == 1) {
                //正式合同生成方式
                contractFleetDtls.forEach(contractFleetDtl -> {

                    if (Integer.valueOf(0).equals(contractFleetDtl.getIsPrepay())) {
                        if (contractFleetDtl.getOilPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getOilPrepayRate()) != 0) {
                            PrepayBill prepayBill = bindDefaultPrepayBillByFeePable(feePayable);
                            officialPrepayBill(feePayable, contractFleetDtl, prepayBill, true, true);
                        }
                        if (contractFleetDtl.getCashPrepayRate() != null && BigDecimal.ZERO.compareTo(contractFleetDtl.getCashPrepayRate()) != 0) {
                            PrepayBill prepayBill = bindDefaultPrepayBillByFeePable(feePayable);
                            officialPrepayBill(feePayable, contractFleetDtl, prepayBill, true, false);
                        }
                    }
                });
            }
        }
    }

    /**
     * 当不存在预付的时候才生成
     *
     * @param prepayBill
     */
    private void checkPrepayBillExistAndInsert(PrepayBill prepayBill) {
        EntityWrapper<PrepayBill> ew = new EntityWrapper<>();
        ew.eq("head_id", prepayBill.getHeadId());
        ew.eq("prepay_type", prepayBill.getPrepayType());
        List<PrepayBill> prepayBillList = baseMapper.selectListNoTenant(ew);
        if (CollectionUtils.isEmpty(prepayBillList)) {
            this.insert(prepayBill);
        }
    }


    /**
     * 根据应付账款生成默认预付帐单数据
     *
     * @param feePayable
     * @return
     */
    @Override
    public PrepayBill bindDefaultPrepayBillByFeePable(FeePayable feePayable) {
        PrepayBill prepayBill = new PrepayBill();

        BeanUtils.copyProperties(feePayable, prepayBill);
        // 默认 - 新增
        if (feePayable.getStartAddr() == null) {
            prepayBill.setStartAddr((feePayable.getStartProvince() == null ? "" : feePayable.getStartProvince())
                    + (feePayable.getStartCity() == null ? "" : feePayable.getStartCity())
                    + (feePayable.getStartCounty() == null ? "" : feePayable.getStartCounty())
                    + (feePayable.getStartAddr() == null ? "" : feePayable.getStartAddr()));
        }
        prepayBill.setEndAddr((feePayable.getEndProvince() == null ? "" : feePayable.getEndProvince())
                + (feePayable.getEndCity() == null ? "" : feePayable.getEndCity())
                + (feePayable.getEndCounty() == null ? "" : feePayable.getEndCounty())
                + (feePayable.getEndAddr() == null ? "" : feePayable.getEndAddr()));
        prepayBill.setStatus(10);
        prepayBill.setGmtCreate(new Date());
        prepayBill.setId(null);
        //设置收款方id和收款方名称为空
        prepayBill.setPayeeId(null);
        prepayBill.setPayeeName(null);
        prepayBill.setHeadId(feePayable.getId());
        //设置承运商id和名称
        prepayBill.setLspId(feePayable.getPayerId());
        prepayBill.setLspName(feePayable.getPayerName());
        prepayBill.setTransModel(feePayable.getTransTypeName());
        return prepayBill;
    }

    /**
     * 审核预付账单
     *
     * @param ids
     */
    @Override
    public void checkPrepayBill(List<Long> ids, int prepayType) {
        if (!CollectionUtils.isEmpty(ids)) {
            //根据id号查询预付账单
            EntityWrapper<PrepayBill> prepayBillEntityWrapper = new EntityWrapper<>();
            prepayBillEntityWrapper.in("id", ids);
            List<PrepayBill> prepayBillList = baseMapper.selectList(prepayBillEntityWrapper);
            //批量审核预付账单
            if (!CollectionUtils.isEmpty(prepayBillList)) {
                if (prepayType == 0 || Objects.deepEquals(prepayType, 0)) {
                    Set<String> prepayBillOrderCodes = new HashSet<>();
                    prepayBillList.forEach(prepayBill -> prepayBillOrderCodes.add(prepayBill.getOrderCode()));

                    EntityWrapper<PrepayBill> eqOrderCodeEw = new EntityWrapper<>();
                    eqOrderCodeEw.in("order_code", prepayBillOrderCodes);
                    eqOrderCodeEw.eq("status", "10");
                    eqOrderCodeEw.eq("prepay_type", "0");
                    List<PrepayBill> eqOrderCodesOilPrepayBillList = baseMapper.selectList(eqOrderCodeEw);

                    if (!CollectionUtils.isEmpty(eqOrderCodesOilPrepayBillList)) {
                        Set<Long> prepayBillHeadIds = new HashSet<>();
                        eqOrderCodesOilPrepayBillList.forEach(prepayBill -> prepayBillHeadIds.add(prepayBill.getHeadId()));
                        Map<String, FcPayApplyDTO> fcPayApplyOrderCodeMap = new HashMap<>();

                        List<FeePayable> feePayables = feePayableService.selectBatchIds(new ArrayList<>(prepayBillHeadIds));
                        Map<Long, FeePayable> feePayableIdHashMap = new HashMap<>();
                        feePayables.forEach(feePayable -> feePayableIdHashMap.put(feePayable.getId(), feePayable));

                        for (PrepayBill prepayBill : eqOrderCodesOilPrepayBillList) {
                            prepayBill.setStatus(20);
                            prepayBill.setSyncStatus("0");
                            String orderCode = prepayBill.getOrderCode();
                            if (fcPayApplyOrderCodeMap.get(orderCode) == null) {
                                FcPayApplyDTO fcPayApplyDTO = new FcPayApplyDTO();
                                fcPayApplyDTO.setShipmentGid(orderCode);
                                fcPayApplyDTO.setPaymentSubject(prepayBill.getPayerName());
                                fcPayApplyDTO.setFleetName(prepayBill.getFleetName());
                                fcPayApplyDTO.setPayType("1");
                                fcPayApplyDTO.setProvider("万金油");
                                fcPayApplyDTO.setApplyForMoney(prepayBill.getPrepayOil());

                                FeePayable feePayable = feePayableIdHashMap.get(prepayBill.getHeadId());
                                if (Objects.nonNull(feePayable)) {
                                    fcPayApplyDTO.setOriginAddr(feePayable.getStartAddr());
                                    fcPayApplyDTO.setDestAddr(feePayable.getEndAddr());
                                }
                                // 车牌号
                                fcPayApplyDTO.setPlateNo(feePayable.getVehicleTypeName());
                                fcPayApplyOrderCodeMap.put(orderCode, fcPayApplyDTO);
                            } else {
                                FcPayApplyDTO fcPayApplyDTO = fcPayApplyOrderCodeMap.get(orderCode);
                                fcPayApplyDTO.setApplyForMoney(fcPayApplyDTO.getApplyForMoney().add(prepayBill.getPrepayOil()));
                                fcPayApplyOrderCodeMap.put(orderCode, fcPayApplyDTO);
                            }
                        }

                        Map<String, String> orderCodeFcCode = new HashMap<>();
                        if (!CollectionUtils.isEmpty(fcPayApplyOrderCodeMap)) {
                            fcPayApplyOrderCodeMap.forEach((s, fcPayApplyDTO) -> orderCodeFcCode.put(s, payApiUtil.createPayapply(fcPayApplyDTO).getData()));
                        }

                        for (PrepayBill prepayBill : eqOrderCodesOilPrepayBillList) {
                            String applyNO = orderCodeFcCode.get(prepayBill.getOrderCode());
                            prepayBill.setCostId(applyNO);
                        }
                        this.updateBatchById(eqOrderCodesOilPrepayBillList);
                    }
                } else {
                    prepayBillList.forEach(prepayBill -> {
                        if (prepayBill.getStatus() == null && prepayBill.getStatus() != 10) {
                            throw new BaseException("在新增状态下才能审核预付账单");
                        } else {
                            prepayBill.setStatus(20);
                        }
                    });
                    updateBatchById(prepayBillList);
                }
            } else {
                throw new BaseException("未查询到需审核的预付账单");
            }
        } else {
            throw new BaseException("请传入预付账单id");
        }

    }

    /**
     * 单个审核
     *
     * @param prepayBill
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void checkPrepayBill(PrepayBill prepayBill) {
        if (prepayBill.getStatus() != null && prepayBill.getStatus() == 10) {
            prepayBill.setStatus(20);
            prepayBill.updateById();
        } else {
            throw new BaseException("在新增状态下才能审核预付账单");
        }
        if (Objects.deepEquals(prepayBill.getPrepayType(), 0)) {
            FeePayable feePayable = feePayableService.selectById(prepayBill.getHeadId());
            FcPayApplyDTO fcPayApplyDTO = new FcPayApplyDTO();
            fcPayApplyDTO.setShipmentGid(prepayBill.getOrderCode());
            fcPayApplyDTO.setPaymentSubject(prepayBill.getPayerName());
            fcPayApplyDTO.setFleetName(prepayBill.getFleetName());
            fcPayApplyDTO.setPayType("1");
            fcPayApplyDTO.setProvider("万金油");
            fcPayApplyDTO.setApplyForMoney(prepayBill.getPrepayOil());
            if (feePayable != null) {
                fcPayApplyDTO.setOriginAddr(feePayable.getStartAddr());
                fcPayApplyDTO.setDestAddr(feePayable.getEndAddr());
            }
            // 车牌
            fcPayApplyDTO.setPlateNo(prepayBill.getVehicleTypeName());
            payApiUtil.createPayapply(fcPayApplyDTO);
        }
    }

    /**
     * 确认预付账单
     *
     * @param ids
     */
    @Override
    public void confirmPrepayBill(List<Long> ids, String bankSerialNum) {
        if (null == bankSerialNum) throw new BaseException("请传入银行流水号");
        if (!CollectionUtils.isEmpty(ids)) {
            //根据id号查询预付账单
            EntityWrapper<PrepayBill> prepayBillEntityWrapper = new EntityWrapper<>();
            prepayBillEntityWrapper.in("id", ids);
            List<PrepayBill> prepayBillList = baseMapper.selectList(prepayBillEntityWrapper);
            //批量确认预付账单
            if (!CollectionUtils.isEmpty(prepayBillList)) {
                for (PrepayBill prepayBill : prepayBillList) {
                    if (prepayBill.getStatus() == null || prepayBill.getStatus() != 20) {
                        throw new BaseException("在审核状态下才能确认预付账单");
                    }
                    if (new Integer(1).equals(prepayBill.getPrepayType())) {
                        if (null == bankSerialNum) throw new BaseException("请传入银行流水号");
                        prepayBill.setBankSerialNum(bankSerialNum);
                    }
                    prepayBill.setStatus(30);
                    prepayBill.updateById();
                }
            } else {
                throw new BaseException("未查询到需审核的预付账单");
            }
        } else {
            throw new BaseException("请传入预付账单id");
        }
    }

    /**
     * 更新预付账单
     *
     * @param ids
     */
    @Override
    public void updatePrepayBill(List<Long> ids) {
        BigDecimal oilPrepayRate = null;
        BigDecimal cashPrepayRate = null;
        BigDecimal prepayCash;
        BigDecimal prepayOil;
        BigDecimal actualAmt;
        if (!CollectionUtils.isEmpty(ids)) {
            //根据id号查询预付账单
            EntityWrapper<PrepayBill> prepayBillEntityWrapper = new EntityWrapper<>();
            prepayBillEntityWrapper.in("id", ids);
            List<PrepayBill> prepayBillList = baseMapper.selectList(prepayBillEntityWrapper);
            if (!CollectionUtils.isEmpty(prepayBillList)) {
                for (PrepayBill prepayBill : prepayBillList) {
                    if (prepayBill.getStatus() == 10) {
                        ////根据运单号明细查询支付价格信息
                        //重新获取支付扣点比例
                        PriceDeductRate priceDeductRate = priceDeductRateService.returnPriceDeductRate(prepayBill.getLspId(), prepayBill.getFleetId());
                        if (Objects.nonNull(priceDeductRate)) {
                            oilPrepayRate = priceDeductRate.getOilPrepayRate();
                            cashPrepayRate = priceDeductRate.getCashPrepayRate();
                        }
                        //重新计算油费预付，现金预付，预付总额
                        if (oilPrepayRate != null && cashPrepayRate != null) {
                            actualAmt = prepayBill.getActualAmt();
                            prepayCash = actualAmt.multiply(cashPrepayRate);
                            prepayOil = actualAmt.multiply(oilPrepayRate);
                            prepayBill.setPrepayCash(prepayCash);
                            prepayBill.setPrepayOil(prepayOil);
                            prepayBill.setPrepaySum(actualAmt.add(prepayCash));
                        }
                        prepayBill.updateById();
                        //PricePurchase pricePurchase = pricePurchaseService.queryPricePurchase(Long.valueOf(prepayBill.getWaybillDtlId()));
                        //if (Objects.nonNull(pricePurchase)) {
                        //    //根据支付价格信息获取结算总金额
                        //    actualAmt = feePayableService.getActualAmt(pricePurchase);
                        //    if (actualAmt != null) {
                        //        //重新获取支付扣点比例
                        //        PriceDeductRate priceDeductRate = priceDeductRateService.returnPriceDeductRate(pricePurchase.getLspId(), pricePurchase.getFleetId());
                        //        if (Objects.nonNull(priceDeductRate)) {
                        //            oilPrepayRate = priceDeductRate.getOilPrepayRate();
                        //            cashPrepayRate = priceDeductRate.getCashPrepayRate();
                        //        }
                        //        //重新计算油费预付，现金预付，预付总额
                        //        if (oilPrepayRate != null && cashPrepayRate != null) {
                        //            actualAmt = prepayBill.getActualAmt();
                        //            prepayCash = actualAmt.multiply(cashPrepayRate);
                        //            prepayOil = actualAmt.multiply(oilPrepayRate);
                        //            prepayBill.setPrepayCash(prepayCash);
                        //            prepayBill.setPrepayOil(prepayOil);
                        //            prepayBill.setPrepaySum(actualAmt.add(prepayCash));
                        //        }
                        //    }
                        //    prepayBill.updateById();
                        //} else {
                        //    throw new BaseException("未获取到支付价格");
                        //}

                    } else {
                        throw new BaseException("在新增状态下才能更新预付账单");
                    }
                }
            } else {
                throw new BaseException("未查询到需审核的预付账单");
            }
        } else {
            throw new BaseException("请传入预付账单id");
        }

    }

    @Override
    public List<PrepayBill> queryPayApplyList(List<Long> billIds) {
        List<BillDetail> billDetailList = billDetailService.getBillDetailList(billIds);
        if (billDetailList.isEmpty()) return null;
        ArrayList<Long> headIds = Lists.newArrayList();
        billDetailList.forEach(billDetail -> {
            headIds.add(billDetail.getFeeId());
        });
        EntityWrapper ew = new EntityWrapper();
        ew.in("head_id", headIds);
        return this.selectList(ew);
    }

    /**
     * 根据账单ID，查询已确认预付账单
     *
     * @param billIds
     * @return
     */
    @Override
    public List<PrepayBill> queryPayApplyAreConfirmList(List<Long> billIds) {
        List<BillDetail> billDetailList = billDetailService.getBillDetailList(billIds);
        if (billDetailList.isEmpty()) return null;
        ArrayList<Long> headIds = Lists.newArrayList();
        billDetailList.forEach(billDetail -> {
            headIds.add(billDetail.getFeeId());
        });
        EntityWrapper ew = new EntityWrapper();
        ew.in("head_id", headIds);
        // 2018-11-22 去掉状态限制
        // ew.eq("status", 30);
        return this.selectList(ew);
    }

    @Override
    public List<PrepayBill> getPayApplyByPayIDList(Long payId) {
        if (ObjectUtils.isEmpty(payId)) return null;
        List<PayApplyDtlPrepay> payApplyDtlPrepaysList = payApplyDtlPrepayService.queryPayApplyDtlPrepayList(payId);
        if (payApplyDtlPrepaysList.isEmpty()) return null;
        List<Long> prepayIds = Lists.newArrayList();
        payApplyDtlPrepaysList.forEach(payApplyDtlPrepays -> {
            if (!ObjectUtils.isEmpty(payApplyDtlPrepays.getBilId())) {
                prepayIds.add(payApplyDtlPrepays.getBilId());
            }
        });
        if (prepayIds.isEmpty()) return null;
        EntityWrapper ew = new EntityWrapper<>();
        ew.in("id", prepayIds);
        return this.selectList(ew);
    }

    /**
     * 根据油卡支付的考核状态对应修改预付帐单状态
     *
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateStateByFcPay(List<Long> ids) {
        try {
            List<PrepayBill> eqOrderCodesOilPrepayBillList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(ids)) {
                //根据id号查询预付账单
                EntityWrapper<PrepayBill> prepayBillEntityWrapper = new EntityWrapper<>();
                prepayBillEntityWrapper.in("id", ids);
                List<PrepayBill> prepayBillList = baseMapper.selectList(prepayBillEntityWrapper);
                //批量审核预付账单
                if (!CollectionUtils.isEmpty(prepayBillList)) {
                    Set<String> prepayBillOrderCodes = new HashSet<>();
                    prepayBillList.forEach(prepayBill -> prepayBillOrderCodes.add(prepayBill.getOrderCode()));

                    EntityWrapper<PrepayBill> eqOrderCodeEw = new EntityWrapper<>();
                    eqOrderCodeEw.in("order_code", prepayBillOrderCodes);
                    eqOrderCodeEw.eq("status", "20");
                    eqOrderCodeEw.eq("prepay_type", "0");
                    eqOrderCodesOilPrepayBillList = baseMapper.selectList(eqOrderCodeEw);
                }
            } else {
                EntityWrapper<PrepayBill> eqOrderCodeEw = new EntityWrapper<>();
                eqOrderCodeEw.eq("status", "20");
                eqOrderCodeEw.eq("prepay_type", "0");
                eqOrderCodesOilPrepayBillList = baseMapper.selectListNoTenant(eqOrderCodeEw);
            }
            if (!CollectionUtils.isEmpty(eqOrderCodesOilPrepayBillList)) {
                Set<String> prepayBillCostIds = new HashSet<>();
                eqOrderCodesOilPrepayBillList.stream()
                        .filter(prepayBill -> !StringUtils.isEmpty(prepayBill.getCostId()))
                        .forEach(prepayBill -> prepayBillCostIds.add(prepayBill.getCostId()));

                Map<String, FcPayApplyReturnDTO> fcPayApplyReturnDTOs = new HashMap<>();
                prepayBillCostIds.forEach(s -> fcPayApplyReturnDTOs.put(s, payApiUtil.getPayApplyAudit(s).getData()));

                eqOrderCodesOilPrepayBillList.forEach(prepayBill -> {
                    FcPayApplyReturnDTO fcPayApplyReturnDTO = fcPayApplyReturnDTOs.get(prepayBill.getCostId());
                    String auditStatusCode = fcPayApplyReturnDTO.getAuditStatusCode();
                    prepayBill.setSyncStatus(auditStatusCode);
                    if ("10".equals(auditStatusCode)) {
                        prepayBill.setStatus(30);
                    }
                });
                this.updateAllColumnBatchById(eqOrderCodesOilPrepayBillList);
            }
        } catch (BaseException e) {
            LOGGER.error("PrepayBillServiceImpl.updateStateByFcPay ERROR: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER.error("PrepayBillServiceImpl.updateStateByFcPay ERROR: {}", e.getMessage());
            throw new BaseException("根据油卡支付的考核状态对应修改预付帐单状态失败");
        }
    }

    /**
     * 加油站第一桶油分页查询
     *
     * @param page
     * @return
     */
    @Override
    public Page<PrepayBillPertrolVO> queryPertrolOilPage(Page<PrepayBillPertrolVO> page) {
        if (page == null) {
            throw new BaseException("分页参数不为空");
        }
        Map<String, Object> condition = page.getCondition();
        addStatusToCondition(condition);
        Wrapper<PrepayBill> ew = buildCondition(condition);
        ew.orderBy("gmt_create desc, id desc");
        List<PrepayBill> prepayBillList = baseMapper.selectPage(page, ew);
        List<PrepayBillPertrolVO> voList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(prepayBillList)) {
            prepayBillList.forEach(prepayBill -> {
                PrepayBillPertrolVO vo = new PrepayBillPertrolVO();
                BeanUtils.copyProperties(prepayBill, vo);
                List<PricePurchaseDetailVO> pricePurchaseDetailList = getPricePurchaseDtlList(prepayBill.getOrderCode(), prepayBill.getWaybillId(), prepayBill.getVin());
                if (!CollectionUtils.isEmpty(pricePurchaseDetailList)) {
                    PricePurchaseDetailVO purchaseDetailVO = pricePurchaseDetailList.get(0);
                    vo.setFirstOilCapacity(purchaseDetailVO.getFirstOilCapacity());
                    vo.setVcorderno(purchaseDetailVO.getVcorderno());
                }
                BigDecimal oilPrice = vo.getPertrolOilPrice() == null ? BigDecimal.ZERO : vo.getPertrolOilPrice();
                BigDecimal firstOil = vo.getFirstOilCapacity() == null ? BigDecimal.ZERO : vo.getFirstOilCapacity();
                vo.setPrepaySum(oilPrice.multiply(firstOil));
                voList.add(vo);
            });
        }
        // page.setRecords(baseMapper.selectPertrolOilPage(page, ew));
        page.setRecords(voList);
        return page;
    }

    private void addStatusToCondition(Map<String, Object> condition) {
        if (Objects.nonNull(condition) && Objects.isNull(condition.get("status"))) {
            condition.put("statusList", "10,20,30");
        }
    }

    /**
     * 根据条件查询
     *
     * @param prepayBillPertrolVO
     * @return
     */
    @Override
    public PrepayBillPertrolVO getPertrolOilCondition(PrepayBillPertrolVO prepayBillPertrolVO) {
        // Wrapper<PrepayBillPertrolVO> ew = new EntityWrapper<>();
        // ew.eq("creator", prepayBillPertrolVO.getCreator());
        // ew.eq("prepay_type", prepayBillPertrolVO.getPrepayType());
        // ew.eq("cus_waybill", prepayBillPertrolVO.getCusWaybill());
        // List<PrepayBillPertrolVO> billPertrolVOList = baseMapper.selectPertrolOilCondition(ew);
        // if (!CollectionUtils.isEmpty(billPertrolVOList)) {
        //     return billPertrolVOList.get(0);
        // }
        PrepayBillPertrolVO pertrolVO = new PrepayBillPertrolVO();
        EntityWrapper<FeePayable> feeEw = new EntityWrapper<>();
        feeEw.eq("cus_waybill", prepayBillPertrolVO.getCusWaybill());
        feeEw.ne("status", 2);
        feeEw.isNotNull("driver_id");
        feeEw.orderBy("id desc");
        List<FeePayable> feePayableList = feePayableService.selectList(feeEw);
        if (!CollectionUtils.isEmpty(feePayableList)) {
            pertrolVO.setCusWaybill(prepayBillPertrolVO.getCusWaybill());
            FeePayable feePayable = feePayableList.get(0);
            EntityWrapper<PrepayBill> prebillEw = new EntityWrapper<>();
            prebillEw.eq("head_id", feePayable.getId());
            prebillEw.eq("creator", prepayBillPertrolVO.getCreator());
            prebillEw.eq("prepay_type", prepayBillPertrolVO.getPrepayType());
            prebillEw.orderBy("id desc");
            List<PrepayBill> prepayBillList = this.selectList(prebillEw);

            if (!CollectionUtils.isEmpty(prepayBillList)) {
                BeanUtils.copyProperties(prepayBillList.get(0), pertrolVO);
                // EntityWrapper<PricePurchaseDetailVO> priceDtlEw = new EntityWrapper<>();
                // priceDtlEw.eq("orderlineId", feePayable.getOrderCode());
                // priceDtlEw.eq("shipment_code", feePayable.getWaybillId());
                // priceDtlEw.eq("item_uid", feePayable.getVin());
                // List<PricePurchaseDetailVO> pricePurchaseDetailList = pricePurchaseDtlMapper.getPricePurchaseDetail(priceDtlEw);
                List<PricePurchaseDetailVO> pricePurchaseDetailList = getPricePurchaseDtlList(feePayable.getOrderCode(), feePayable.getWaybillId(), feePayable.getVin());
                if (!CollectionUtils.isEmpty(pricePurchaseDetailList)) {
                    PricePurchaseDetailVO purchaseDetailVO = pricePurchaseDetailList.get(0);
                    pertrolVO.setFirstOilCapacity(purchaseDetailVO.getFirstOilCapacity());
                    pertrolVO.setVcorderno(purchaseDetailVO.getVcorderno());
                }
                return pertrolVO;
            }
        }
        return null;
    }

    private List<PricePurchaseDetailVO> getPricePurchaseDtlList(String orderCode, String waybillId, String vin) {
        EntityWrapper<PricePurchaseDetailVO> priceDtlEw = new EntityWrapper<>();
        priceDtlEw.eq("orderlineId", orderCode);
        priceDtlEw.eq("shipment_code", waybillId);
        priceDtlEw.eq("item_uid", vin);
        return pricePurchaseDtlMapper.getPricePurchaseDetail(priceDtlEw);
    }

    /**
     * 更新缺人加油状态
     *
     * @param prepayBill
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updatePertrolOilStatue(PrepayBill prepayBill) {
        if (prepayBill == null || prepayBill.getId() == null) {
            throw new BaseException("参数为空");
        }
        PrepayBill oldPrepaybill = this.selectById(prepayBill.getId());
        if (oldPrepaybill == null) {
            throw new BaseException("找不到对应的预付账单");
        }
        if (Integer.valueOf(1).equals(oldPrepaybill.getPertrolOilStatus())) {
            throw new BaseException("已确认, 不可重复确认!");
        }
        FeePayable feePayable = null;
        if (Objects.nonNull(oldPrepaybill.getHeadId())) {
            feePayable = feePayableService.selectById(oldPrepaybill.getHeadId());
        }
        if (Objects.nonNull(feePayable)) {
            String podStatus = verifyReturnStatus(feePayable.getWaybillDtlId());
            if (!StringUtils.isEmpty(podStatus)) {
                throw new BaseException("当前指令回单不可加油确认!");
            }
        }

        prepayBill.setPertrolOilStatus(1);
        prepayBill.setPertrolOilDate(new Date());
        // 2019-06-05 根据加油确认时间的确定加油站油价
        // if (Objects.nonNull(oldPrepaybill.getHeadId())) {
        if (Objects.nonNull(feePayable)) {
            // FeePayable feePayable = feePayableService.selectById(oldPrepaybill.getHeadId());
            if (Objects.nonNull(feePayable)) {
                prepayBill.setPertrolOilPrice(pricePurchaseService.getPertrolOilPrice(feePayable.getVehicleClassifyId(), prepayBill.getPertrolOilDate()));
            }
        }
        this.updateById(prepayBill);
    }

    private String verifyReturnStatus(String waybillDtlId) {
        // 校验是否回单, 已回单不可加油确认
        if (!StringUtils.isEmpty(waybillDtlId)) {
            EntityWrapper<WaybillState> ew = new EntityWrapper<>();
            ew.eq("order_release_gid", "ULC/ZC." + waybillDtlId);
            List<WaybillState> waybillStateList = waybillStateService.selectList(ew);
            if (!CollectionUtils.isEmpty(waybillStateList)) {
                return waybillStateList.get(0).getPodStatus();
            }
        }
        return null;
    }

    /**
     * 根据条件获取所有匹配数据
     *
     * @param condition
     * @return
     */
    @Override
    public List<PrepayBillPertrolVO> queryPertrolOilPrepayBillList(Map<String, Object> condition) {
        addStatusToCondition(condition);
        Wrapper<PrepayBill> ew = buildCondition(condition);
        ew.orderBy("gmt_create desc, id desc");
        List<PrepayBill> prepayBillList = baseMapper.selectList(ew);
        List<PrepayBillPertrolVO> voList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(prepayBillList)) {
            prepayBillList.forEach(prepayBill -> {
                PrepayBillPertrolVO vo = new PrepayBillPertrolVO();
                BeanUtils.copyProperties(prepayBill, vo);
                List<PricePurchaseDetailVO> pricePurchaseDetailList = getPricePurchaseDtlList(prepayBill.getOrderCode(), prepayBill.getWaybillId(), prepayBill.getVin());
                if (!CollectionUtils.isEmpty(pricePurchaseDetailList)) {
                    PricePurchaseDetailVO purchaseDetailVO = pricePurchaseDetailList.get(0);
                    vo.setFirstOilCapacity(purchaseDetailVO.getFirstOilCapacity());
                    vo.setVcorderno(purchaseDetailVO.getVcorderno());
                }
                voList.add(vo);
            });
        }
        return voList;
    }

    /**
     * 根据油卡支付的考核状态对应修改预付帐单状态
     *
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updatePertrolOilPrice(List<Long> ids) {
        if (!CollectionUtils.isEmpty(ids)) {
            List<PrepayBill> prepayBillList = this.selectBatchIds(ids);
            // if (!CollectionUtils.isEmpty(prepayBillList)) {
            //     prepayBillList.stream().filter(prepayBill -> Objects.nonNull(prepayBill.getPertrolOilDate())).forEach(prepayBill -> {
            //         FeePayable feePayable = feePayableService.selectById(prepayBill.getHeadId());
            //         // Date effectDate = feePayable.getOrderDate() == null ? feePayable.getGmtCreate() : feePayable.getOrderDate();
            //         // 2019-06-05 用加油站确认加油更新
            //         prepayBill.setPertrolOilPrice(pricePurchaseService.getPertrolOilPrice(feePayable.getVehicleClassifyId(), prepayBill.getPertrolOilDate()));
            //     });
            //     this.updateBatchById(prepayBillList);
            // }
            this.commonBatchUpdatePertrolOilPrice(prepayBillList);
        }
    }

    /**
     * 无登录用户查询
     *
     * @param ew
     * @return
     */
    @Override
    public List<PrepayBill> selectListNoTenant(Wrapper<PrepayBill> ew) {
        return baseMapper.selectListNoTenant(ew);
    }

    /**
     * 更新发运状态
     *
     * @param orderCode
     */
    @Override
    public void updateHuiyuncheLoadStatusByOrderCode(String orderCode) {
        if (!StringUtils.isEmpty(orderCode)) {
            baseMapper.updateHuiyuncheLoadStatusByOrderCode(orderCode);
        }
    }

    /**
     * 根据条件更新第一桶油价
     *
     * @param condition
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateBatchPertrolOilPriceByCondition(Map<String, Object> condition) {
        addStatusToCondition(condition);
        Wrapper<PrepayBill> ew = buildCondition(condition);
        ew.orderBy("gmt_create desc, id desc");
        List<PrepayBill> prepayBillList = baseMapper.selectList(ew);
        this.commonBatchUpdatePertrolOilPrice(prepayBillList);
    }

    /**
     * 生成预付账单
     *
     * @param feePayable
     * @param contract
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void createPrepayBillByContract(FeePayable feePayable, Contract contract) {
        /**
         * 2019-06-04 修改 - 当有合同却没有报价单的时候根据标准价生成预付
         */
        if (Objects.nonNull(contract)) {
            if (Objects.nonNull(feePayable.getActualAmt()) && BigDecimal.ZERO.compareTo(feePayable.getActualAmt()) != 0) {
                // 根据合同价生成预付单
                createPrepayBillByActualPrice(contract, feePayable);
            } else if (Objects.nonNull(feePayable.getEstAmt()) && BigDecimal.ZERO.compareTo(feePayable.getEstAmt()) != 0) {
                // 根据标准价生成预付单
                createPrepayBillByEstPrice(contract, feePayable);
            }
        }
    }

    /**
     * 根据条件获取所有匹配数据-针对打印金额
     *
     * @param condition
     * @return
     */
    @Override
    public Map<String, Object> queryPrepayBillForPrint(Map<String, Object> condition) {
        Map<String, Object> resultData = Maps.newHashMap();
        resultData.put("dataList", this.queryPrepayBillList(condition));

        PrepayBill prepayBill = baseMapper.sumPrebillCashNoTenant(condition);
        if (Objects.nonNull(prepayBill)) {
            Map<String, Object> sumMap = Maps.newHashMap();
            // 本次预付
            sumMap.put("currentPaySum", Objects.nonNull(prepayBill.getPrepaySum()) ? prepayBill.getPrepaySum() : BigDecimal.ZERO);
            sumMap.put("alreadyPaySum", Objects.nonNull(prepayBill.getPrepayCash()) ? prepayBill.getPrepayCash() : BigDecimal.ZERO);
            sumMap.put("notPaySum", Objects.nonNull(prepayBill.getPrepayOil()) ? prepayBill.getPrepayOil() : BigDecimal.ZERO);
            resultData.put("sumData", sumMap);
        }
        return resultData;
    }

    /**
     * 批量更新市场油价
     *
     * @param prepayBillList
     */
    private void commonBatchUpdatePertrolOilPrice(List<PrepayBill> prepayBillList) {
        if (!CollectionUtils.isEmpty(prepayBillList)) {
            prepayBillList.stream().filter(prepayBill -> Objects.nonNull(prepayBill.getPertrolOilDate())).forEach(prepayBill -> {
                FeePayable feePayable = feePayableService.selectById(prepayBill.getHeadId());
                prepayBill.setPertrolOilPrice(pricePurchaseService.getPertrolOilPrice(feePayable.getVehicleClassifyId(), prepayBill.getPertrolOilDate()));
            });
            this.updateBatchById(prepayBillList);
        }
    }
}
